package com.sgcc.activiti.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sgcc.activiti.domain.*;
import com.sgcc.activiti.mapper.OAnomalyInfoMapper;
import com.sgcc.activiti.mapper.OContentAdSchemaMapper;
import com.sgcc.activiti.mapper.OContentAppSchemaMapper;
import com.sgcc.activiti.mapper.TaskMapper;
import com.sgcc.activiti.service.*;
import com.sgcc.common.core.constant.HttpStatus;
import com.sgcc.common.core.domain.R;
import com.sgcc.common.core.utils.FastJsonUtil;
import com.sgcc.common.core.utils.HttpClientUtil;
import com.sgcc.common.core.utils.ServletUtils;
import com.sgcc.common.core.utils.StringUtils;
import com.sgcc.common.core.web.domain.AjaxResult;
import com.sgcc.common.core.web.page.TableDataInfo;
import com.sgcc.common.security.service.TokenService;
import com.sgcc.system.api.RemoteIscService;
import com.sgcc.system.api.RemoteUserService;
import com.sgcc.system.api.domain.SysUser;
import com.sgcc.system.api.model.LoginUser;
import lombok.AllArgsConstructor;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricActivityInstanceQuery;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.persistence.entity.TaskEntityImpl;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.runtime.ProcessInstanceQuery;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.DelegationState;
import org.activiti.engine.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

//import com.sgcc.system.mapper.SysUserMapper;

/**
 * @author 一只闲鹿
 */
@Service
@Transactional
@AllArgsConstructor
public class ProcessServiceImpl implements IProcessService {

    protected final Logger logger = LoggerFactory.getLogger(ProcessServiceImpl.class);
    private IOMonTarService monTarService;
    private IdentityService identityService;
    private TaskService taskService;
    private HistoryService historyService;
    private RuntimeService runtimeService;
    //    private SysUserMapper userMapper;
    private TaskMapper taskMapper;
    private TokenService tokenService;

    private RemoteUserService remoteUserService;

    private RemoteIscService remoteIscService;
    @Autowired
    private OContentAdSchemaMapper oContentAdSchemaService;
    @Autowired
    private OAnomalyInfoMapper oAnomalyInfoMapper;
    @Autowired
    private OContentAppSchemaMapper oContentAppSchemaService;

    @Autowired
    private IOInterfaceIndexService interfaceIndexService;

    @Autowired
    private IOContentAppPicService oContentAppPicService;


    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    /**
     * 提交申请
     */
    @Override
    public <T> void submitApply(T entity, String key) throws Exception {
        this.submitApply(entity, key, null);
    }

    @Override
    public <T> void submitApplyAdmin(T entity, String key, String username) throws Exception {
        Class clazz = entity.getClass();

        Method getId = clazz.getDeclaredMethod("getId");
        String id = (String) getId.invoke(entity);

        Method setApplyUserId = clazz.getDeclaredMethod("setApplyUserId", String.class);
        Method setApplyUserName = clazz.getDeclaredMethod("setApplyUserName", String.class);
        Method setApplyTime = clazz.getDeclaredMethod("setApplyTime", Date.class);
        Method setProcessKey = clazz.getDeclaredMethod("setProcessKey", String.class);

        Method setUpdateBy = clazz.getSuperclass().getSuperclass().getDeclaredMethod("setUpdateBy", String.class);
        Method setUpdateTime = clazz.getSuperclass().getSuperclass().getDeclaredMethod("setUpdateTime", Date.class);

        Method setInstanceId = clazz.getDeclaredMethod("setInstanceId", String.class);

        String nickName = username;
        Date now = new Date();

        // 更新流程通用字段
        setApplyUserId.invoke(entity, username);
        setApplyUserName.invoke(entity, nickName);
        setApplyTime.invoke(entity, now);
        setProcessKey.invoke(entity, key);
        setUpdateBy.invoke(entity, username);
        setUpdateTime.invoke(entity, now);

        // 用来设置启动流程的人员ID，引擎会自动把用户ID保存到activiti:initiator中
        identityService.setAuthenticatedUserId(username);
        // 启动流程时设置业务 key
        ProcessInstance instance = runtimeService.startProcessInstanceByKey(key, id + "", null);

        // 更新业务表流程实例id字段
        setInstanceId.invoke(entity, instance.getId());

        // 记录流程实例业务关系
        InstanceBusiness ib = new InstanceBusiness();
        ib.setInstanceId(instance.getId());
        ib.setBusinessKey(id + "");
        ib.setModule(humpToLine(entity.getClass().getSimpleName()).substring(1));
        taskMapper.insertInstanceBusiness(ib);
    }

    @Override
    public <T> void submitApply(T entity, String key, Map<String, Object> variables) throws Exception {
        LoginUser user = tokenService.getLoginUser(ServletUtils.getRequest());
        Class clazz = entity.getClass();

        Method getId = clazz.getDeclaredMethod("getId");
        String id = (String) getId.invoke(entity);

        Method setApplyUserId = clazz.getDeclaredMethod("setApplyUserId", String.class);
        Method setApplyUserName = clazz.getDeclaredMethod("setApplyUserName", String.class);
        Method setApplyTime = clazz.getDeclaredMethod("setApplyTime", Date.class);
        Method setProcessKey = clazz.getDeclaredMethod("setProcessKey", String.class);

        Method setUpdateBy = clazz.getSuperclass().getSuperclass().getDeclaredMethod("setUpdateBy", String.class);
        Method setUpdateTime = clazz.getSuperclass().getSuperclass().getDeclaredMethod("setUpdateTime", Date.class);

        Method setInstanceId = clazz.getDeclaredMethod("setInstanceId", String.class);

        String username = "admin";
        String nickName = "admin";
        if (user != null) {
            username = user.getUsername();
            nickName = user.getUsername();
        }

        Date now = new Date();

        // 更新流程通用字段
        setApplyUserId.invoke(entity, username);
        setApplyUserName.invoke(entity, nickName);
        setApplyTime.invoke(entity, now);
        setProcessKey.invoke(entity, key);
        setUpdateBy.invoke(entity, username);
        setUpdateTime.invoke(entity, now);

        // 用来设置启动流程的人员ID，引擎会自动把用户ID保存到activiti:initiator中
        identityService.setAuthenticatedUserId(username);
        // 启动流程时设置业务 key
        ProcessInstance instance = runtimeService.startProcessInstanceByKey(key, id + "", variables);

        // 更新业务表流程实例id字段
        setInstanceId.invoke(entity, instance.getId());

        // 记录流程实例业务关系
        InstanceBusiness ib = new InstanceBusiness();
        ib.setInstanceId(instance.getId());
        ib.setBusinessKey(id + "");
        ib.setModule(humpToLine(entity.getClass().getSimpleName()).substring(1));
        taskMapper.insertInstanceBusiness(ib);
    }

    /**
     * 驼峰转下划线
     */
    private String humpToLine(String str) {
        Pattern humpPattern = Pattern.compile("[A-Z]");
        Matcher matcher = humpPattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    /**
     * 下划线转驼峰
     */
    public static String lineToHump(String str) {
        str = str.toLowerCase();
        Pattern linePattern = Pattern.compile("_(\\w)");
        Matcher matcher = linePattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    /**
     * 填充流程相关字段
     */
    @Override
    public <T> void richProcessField(T entity) throws Exception {
        Class clazz = entity.getClass();

        Method getInstanceId = clazz.getDeclaredMethod("getInstanceId");
        String instanceId = (String) getInstanceId.invoke(entity);

        Method setTaskId = clazz.getSuperclass().getDeclaredMethod("setTaskId", String.class);
        Method setTaskName = clazz.getSuperclass().getDeclaredMethod("setTaskName", String.class);
        Method setSuspendState = clazz.getSuperclass().getDeclaredMethod("setSuspendState", String.class);
        Method setSuspendStateName = clazz.getSuperclass().getDeclaredMethod("setSuspendStateName", String.class);

        // 当前环节
        if (StringUtils.isNotBlank(instanceId)) {
            List<Task> taskList = taskService.createTaskQuery()
                    .processInstanceId(instanceId)
                    .list();    // 例如请假会签，会同时拥有多个任务
            if (!CollectionUtils.isEmpty(taskList)) {
                TaskEntityImpl task = (TaskEntityImpl) taskList.get(0);
                setTaskId.invoke(entity, task.getId());
                if (task.getSuspensionState() == 2) {
//                    setTaskName.invoke(entity, "已锁定");
                    setTaskName.invoke(entity, task.getName());
                    setSuspendState.invoke(entity, "2");
                    setSuspendStateName.invoke(entity, "已锁定");
                } else {
                    setTaskName.invoke(entity, task.getName());
                    setSuspendState.invoke(entity, "1");
                    setSuspendStateName.invoke(entity, "已激活");
                }
            } else {
                // 已办结或者已撤销
                List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery()
                        .processInstanceId(instanceId)
                        .orderByTaskCreateTime()
                        .desc()
                        .list();
                if (!CollectionUtils.isEmpty(list)) {
                    HistoricTaskInstance lastTask = list.get(0); // 该流程实例最后一个任务
                    if (StringUtils.isNotBlank(lastTask.getDeleteReason())) {
                        setTaskName.invoke(entity, "已终止");
                    } else {
                        setTaskName.invoke(entity, "已结束");
                    }
                    setTaskId.invoke(entity, "-1"); // 已撤销或已结束，任务id不妨设置成-1
                } else {
                    // 这种情况是流程表被删除，业务表的instanceId找不到对应记录
                    setTaskName.invoke(entity, "流程已删除");
                    setTaskId.invoke(entity, "-2"); // 流程已删除，前端不能查看审批历史和进度
                }
            }
        } else {
            setTaskName.invoke(entity, "未启动");
        }
    }

    @Override
    public TableDataInfo findTodoTasks(TaskVo taskVo) {
        LoginUser user = tokenService.getLoginUser(ServletUtils.getRequest());
        taskVo.setUserId(user.getUsername());
        taskVo.setOffset((taskVo.getPageNum() - 1) * taskVo.getPageSize());
        List<Map> tasks = taskMapper.findTodoList(taskVo);
        Integer count = taskMapper.findTodoCount(taskVo);

        List<TaskVo> taskVos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(tasks)) {
            tasks.forEach(task -> {
                TaskVo newTaskVo = new TaskVo();
                newTaskVo.setType("todo");
                newTaskVo.setUserId(user.getUsername());
                newTaskVo.setTaskId(task.get("ID_").toString());
                newTaskVo.setTaskName(task.get("NAME_").toString());
                newTaskVo.setInstanceId(task.get("PROC_INST_ID_").toString());
                newTaskVo.setSuspendState(task.get("SUSPENSION_STATE_").toString());
                newTaskVo.setCreateTime((Date) task.get("CREATE_TIME_"));
                newTaskVo.setProcessId(String.valueOf(task.get("TASK_DEF_KEY_")));
                try {
                    newTaskVo.setId(task.get("business_key").toString());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    newTaskVo.setModule(task.get("module").toString());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    newTaskVo.setUpdateBy(task.get("update_by").toString());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    newTaskVo.setUpdateTime((Date) task.get("update_time"));
                } catch (Exception e) {
                    e.printStackTrace();
                }


                newTaskVo.setAssigneeName(user.getUsername());

                // 查询业务表单数据，放入 map 中
                Map ibMap = taskMapper.selectInstanceBusinessByInstanceId(task.get("PROC_INST_ID_").toString());
                System.out.println(ibMap);
                if (!CollectionUtils.isEmpty(ibMap)) {
                    Map<String, Object> formData = taskMapper.selectBusinessByBusinessKeyAndModule(ibMap.get("business_key").toString(), ibMap.get("module").toString());
                    if (!CollectionUtils.isEmpty(formData)) {
                        Map<String, Object> formDataMap = getLine2HumpMap(formData);
                        formDataMap.put("suspendState", newTaskVo.getSuspendState());
                        formDataMap.put("processId", String.valueOf(task.get("TASK_DEF_KEY_")));
                        newTaskVo.setFormData(formDataMap);
                    }
                }
                if ("2".equals(newTaskVo.getSuspendState())) {
                    newTaskVo.setSuspendStateName("已锁定");
                } else {
                    newTaskVo.setSuspendStateName("已激活");
                }

                taskVos.add(newTaskVo);
            });
        }

        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");
        rspData.setRows(taskVos);
        rspData.setTotal(count);

        return rspData;
    }

    private Map<String, Object> getLine2HumpMap(Map<String, Object> map) {
        Map<String, Object> newMap = new HashMap<>();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            // key 格式转换，如 apply_user_id 转换成 applyUserId
            key = lineToHump(key).substring(0, 1).toLowerCase() + lineToHump(key).substring(1);
            newMap.put(key, value);
        }
        return newMap;
    }

    @Override
    public TableDataInfo findDoneTasks(TaskVo taskVo) {
        LoginUser user = tokenService.getLoginUser(ServletUtils.getRequest());
        taskVo.setUserId(user.getUsername());
        taskVo.setOffset((taskVo.getPageNum() - 1) * taskVo.getPageSize());
        List<Map> tasks = taskMapper.findDoneList(taskVo);
        Integer count = taskMapper.findDoneCount(taskVo);

        List<TaskVo> taskVos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(tasks)) {
            tasks.forEach(task -> {
                TaskVo newTaskVo = new TaskVo();
                newTaskVo.setType("done");
                newTaskVo.setUserId(user.getUsername());
                newTaskVo.setTaskId(task.get("ID_").toString());
                newTaskVo.setTaskName(task.get("NAME_").toString());
                newTaskVo.setInstanceId(task.get("PROC_INST_ID_").toString());
                newTaskVo.setAssignee(task.get("ASSIGNEE_").toString());
                newTaskVo.setStartTime((Date) task.get("START_TIME_"));
                newTaskVo.setEndTime((Date) task.get("END_TIME_"));
                try {
                    newTaskVo.setId(task.get("business_key").toString());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    newTaskVo.setModule(task.get("module").toString());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    newTaskVo.setUpdateBy(task.get("update_by").toString());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    newTaskVo.setUpdateTime((Date) task.get("update_time"));
                } catch (Exception e) {
                    e.printStackTrace();
                }
                newTaskVo.setAssigneeName(remoteUserService.selectUserByUserName(newTaskVo.getAssignee()).getNickName());

                // 查询业务表单数据，放入 map 中
                Map ibMap = taskMapper.selectInstanceBusinessByInstanceId(task.get("PROC_INST_ID_").toString());
                if (!CollectionUtils.isEmpty(ibMap)) {
                    Map<String, Object> formData = taskMapper.selectBusinessByBusinessKeyAndModule(ibMap.get("business_key").toString(), ibMap.get("module").toString());
                    if (!CollectionUtils.isEmpty(formData)) {
                        Map<String, Object> formDataMap = getLine2HumpMap(formData);
                        formDataMap.put("processId", String.valueOf(task.get("TASK_DEF_KEY_")));
                        newTaskVo.setFormData(formDataMap);
                    }
                }

                taskVos.add(newTaskVo);
            });
        }

        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");
        rspData.setRows(taskVos);
        rspData.setTotal(count);

        return rspData;
    }

    private Boolean publicOContentAppSchema(JSONObject formDate) {
        OInterfaceIndex oInterfaceIndex = interfaceIndexService.selectAddressbycode("0101115");
        String rpcInterface = "test";
        if (null != oInterfaceIndex && null != oInterfaceIndex.getInterfaceAdress()) {
            rpcInterface = oInterfaceIndex.getInterfaceAdress();
        }
        String serviceType = formDate.getString("serviceType");
        int resultCode = 0;
        if ("01".equals(serviceType)) {
            if ("test".equals(rpcInterface)) {
                resultCode = 1;
            } else {
                String params = "";
                //构建参数
                /**
                 * {
                 "serviceCode":"0101115",
                 "target":"35101",
                 "source":"SGAPP",
                 "data":{
                 "platformId":"35101",
                 "serialNum":"d567cf117aa24c41b07e6ddd25a4b409",
                 "serviceType":"01",
                 "contentTitle":"心的乌镇来了就不曾离开-0",
                 "contentType":"0",
                 "mationType":"1",
                 "contentScene":"3",
                 "contentDetails":"资讯描述",
                 "bannerPicId":"001a3de7edd247fb9984fc8752689772",
                 "releaseScope":"35101",
                 "pulishType":"浙江精1",
                 "contentApp":"<div><p><img src=\"001a3de7edd247fb9984fc8752689772\" alt=\"\"></p><p>报道称，该论坛有超过50家的日本企业巨头、中日企域等发挥相互优势，开拓海外市场。</p><div></div></div>",
                 "contentIsStick":"1",
                 "contentPicIds":"001a3de7edd247fb9984fc8752689772,1"
                 }
                 * }
                 */
                Map paramsData = new HashMap();
                String contentPicids = formDate.getString("contentPicids");
                String appIds = "";
                if (StringUtils.isNotBlank(contentPicids)) {
                    String[] picids = contentPicids.split(",");
                    for (int i = 0; i < picids.length; i++) {
                        OContentAppPic pic = oContentAppPicService.selectOContentAppPicById(picids[i]);
                        if (pic != null) {
                            appIds = appIds + "," + pic.getAppId();
                        }
                    }
                }
                paramsData.put("platformId", "350000");
                paramsData.put("serialNum", formDate.getString("newId"));
                paramsData.put("serviceType", "01");
                paramsData.put("contentTitle", formDate.getString("contentTitle"));
                paramsData.put("contentType", "0");
                paramsData.put("mationType", formDate.getString("mationType"));
                paramsData.put("contentScene", formDate.getString("contentScene"));
                paramsData.put("contentDetails", formDate.getString("contentDetails"));
                paramsData.put("releaseScope", "350000");
                paramsData.put("pulishType", formDate.getString("publishType"));
                paramsData.put("contentApp", formDate.getString("contentApp"));
                paramsData.put("contentAuthor", formDate.getString("contentAuthor"));
                paramsData.put("contentIsStick", "1");
                paramsData.put("bannerPicId", oContentAppPicService.selectOContentAppPicById(formDate.getString("bannerpicId")) == null ? null : oContentAppPicService.selectOContentAppPicById(formDate.getString("bannerpicId")).getAppId());
                paramsData.put("contentPicIds", appIds);

                Map map = new HashMap();
                map.put("serviceCode", "0101115");
                map.put("source", "SGAPP");
                map.put("target", "35101");
                map.put("data", paramsData);
                params = FastJsonUtil.toJSONString(map);
                String rpcResultStr = HttpClientUtil.sendJsonStr(rpcInterface, params).getData();
                //解析返回值
                R oContentAdResult = FastJsonUtil.toBean(rpcResultStr, R.class);
                resultCode = oContentAdResult.getCode();
            }
        } else if ("02".equals(serviceType)) {
            if ("test".equals(rpcInterface)) {
                resultCode = 1;
            } else {
                String params = "";
                Map paramsData = new HashMap();
                String contentPicids = formDate.getString("contentPicids");
                ;
                String appIds = "";
                if (StringUtils.isNotBlank(contentPicids)) {
                    String[] picids = contentPicids.split(",");
                    for (int i = 0; i < picids.length; i++) {
                        OContentAppPic pic = oContentAppPicService.selectOContentAppPicById(picids[i]);
                        if (pic != null) {
                            appIds = appIds + "," + pic.getAppId();
                        }
                    }
                }
                paramsData.put("platformId", "350000");
                paramsData.put("serialNum", formDate.getString("newId"));
                paramsData.put("serviceType", "02");
                paramsData.put("contentTitle", formDate.getString("contentTitle"));
                paramsData.put("contentType", "0");
                paramsData.put("mationType", formDate.getString("mationType"));
                paramsData.put("contentScene", formDate.getString("contentScene"));
                paramsData.put("contentDetails", formDate.getString("contentDetails"));
                paramsData.put("releaseScope", "350000");
                paramsData.put("pulishType", formDate.getString("publishType"));
                paramsData.put("contentApp", formDate.getString("contentApp"));
                paramsData.put("contentAuthor", formDate.getString("contentAuthor"));
                paramsData.put("contentIsStick", "1");
                paramsData.put("bannerPicId", oContentAppPicService.selectOContentAppPicById(formDate.getString("bannerpicId")) == null ? null : oContentAppPicService.selectOContentAppPicById(formDate.getString("bannerpicId")).getAppId());
                paramsData.put("contentPicIds", appIds);

                Map map = new HashMap();
                map.put("serviceCode", "0101123");
                map.put("source", "SGAPP");
                map.put("target", "35101");
                map.put("data", paramsData);
                params = FastJsonUtil.toJSONString(map);
                String rpcResultStr = HttpClientUtil.sendJsonStr(rpcInterface, params).getData();
                //解析返回值
                R r = FastJsonUtil.toBean(rpcResultStr, R.class);
                resultCode = r.getCode();
            }
        } else {
//            throw new Exception("资讯维护类型错误");
            return false;
        }
        if (1 != resultCode) {
//            throw new Exception("远程调用接收参数失败");
            return false;
        }
        return true;
    }

    @Override
    public AjaxResult complete(String taskId, String instanceId, String variablesStr) {
        LoginUser user = tokenService.getLoginUser(ServletUtils.getRequest());
        String username = null == user ? "admin" : user.getUsername();
        System.out.println("variables: " + variablesStr);
        Map<String, Object> variables = (Map<String, Object>) JSON.parse(variablesStr);
        String comment = variables.get("comment").toString();
        String pass = variables.get("pass").toString();//是否审批通过
        Object obj = variables.get("formData");//类型
        JSONObject formDate = JSONObject.parseObject(obj.toString());
        try {
            variables.put("pass", Boolean.valueOf(pass));
            try {
                String serviceType = formDate.getString("serviceType");//是否审批通过
                variables.put("serviceType", serviceType);
            } catch (Exception e) {
                System.out.println("没有serviceType");
//                e.printStackTrace();
            }
            try {
                String publishResults = variables.get("publishResultsn ").toString();//是否审批通过
                variables.put("publishResults", publishResults);
            } catch (Exception e) {
                System.out.println("没有publishResults");
//                e.printStackTrace();
            }

            Map<String, Object> maps = taskMapper.findByInstanceId(instanceId);

            if (maps != null) {
                String module = String.valueOf(maps.get("module"));
                String business_key = String.valueOf(maps.get("business_key"));
//                String userName= user.getUsername();
                //异常监控流待处理
                if ("o_anomaly_info".equals(module) && !Boolean.valueOf(pass)) {
                    OAnomalyInfo oAnomalyInfo = oAnomalyInfoMapper.selectOAnomalyInfoById(business_key);

                    oAnomalyInfo.setExtrField2("1");

                    oAnomalyInfo.setHandleDesc(comment);
                    oAnomalyInfoMapper.updateOAnomalyInfo(oAnomalyInfo);
                    return AjaxResult.success();
                }
            }
//            if(null!=maps) {
//                String module = String.valueOf(maps.get("module"));
//                String business_key = String.valueOf(maps.get("business_key"));
//                if("o_content_ad_schema".equals(module) &&("f3".equals(formDate.getString("processId"))||"f4".equals(formDate.getString("processId")))){
//                  Boolean pss=  publicOContentAppSchema(formDate);
//                  variables.put("publishResults",pss?"01":"02");
//                }
//                if("o_content_app_schema".equals(module) ){
//                    OContentAppSchema oContentAppSchema =oContentAppSchemaService.selectOContentAppSchemaById(business_key);
//
//                }
//            }


            // 被委派人处理完成任务
            // p.s. 被委托的流程需要先 resolved 这个任务再提交。
            // 所以在 complete 之前需要先 resolved

            // 判断该任务是否是委托任务（转办）
            TaskEntityImpl task = (TaskEntityImpl) taskService.createTaskQuery()
                    .taskId(taskId)
                    .singleResult();
            // DELEGATION_ 为 PENDING 表示该任务是转办任务
            if (task.getDelegationState() != null && task.getDelegationState().equals(DelegationState.PENDING)) {
                taskService.resolveTask(taskId, variables);
                // 批注说明是转办
                String delegateUserName = "";
//                remoteUserService.selectUserByUserName(username).getNickName();
                comment += "【由" + delegateUserName + "转办】";

                // 如果是 OWNER_ 为 null 的转办任务（候选组的待办），暂且用转办人来签收该任务
                if (StringUtils.isBlank(task.getOwner())) {
                    taskService.claim(taskId, username);
                }
            } else {
                taskService.claim(taskId, username);
                // 只有签收任务，act_hi_taskinst 表的 assignee 字段才不为 null

            }

            if (StringUtils.isNotEmpty(comment)) {
                identityService.setAuthenticatedUserId(username);
                taskService.addComment(taskId, instanceId, comment);
            }
            RuntimeService runtimeService = processEngine.getRuntimeService();

            taskService.complete(taskId, variables);


            if (null != maps) {
                String module = String.valueOf(maps.get("module"));
                String business_key = String.valueOf(maps.get("business_key"));
//                String userName= user.getUsername();
                //异常监控流程处理结束
                if ("o_anomaly_info".equals(module) && "f2".equals(formDate.getString("processId"))) {
                    OAnomalyInfo oAnomalyInfo = oAnomalyInfoMapper.selectOAnomalyInfoById(business_key);
                    oAnomalyInfo.setFinishTime(new Date());
                    Double duration = Double.valueOf(new Date().getTime() - oAnomalyInfo.getOccTime().getTime()) / 60 / 60 / 1000;
                    oAnomalyInfo.setDuration(BigDecimal.valueOf(duration));
                    oAnomalyInfo.setExtrField2("2");
                    oAnomalyInfoMapper.updateOAnomalyInfo(oAnomalyInfo);
                }
                if ("o_content_ad_schema".equals(module)) {

                    OContentAdSchema oContentAdSchema = oContentAdSchemaService.selectOContentAdSchemaById(business_key);
                    if (!"03".equals(oContentAdSchema.getServiceType())) {
                        if ((!Boolean.valueOf(pass) && "修改".equals(comment)) || "f1".equals(formDate.getString("processId"))) {
                            oContentAdSchema = formDate.toJavaObject(OContentAdSchema.class);
                        }
                    }

                    oContentAdSchema.setUpdateDate(new Date());
                    oContentAdSchemaService.updateOContentAdSchema(oContentAdSchema);
                }
                if ("o_content_app_schema".equals(module)) {
                    OContentAppSchema oContentAppSchema = oContentAppSchemaService.selectOContentAppSchemaById(business_key);
                    if (!"03".equals(oContentAppSchema.getServiceType())) {
                        if ((!Boolean.valueOf(pass) && "修改".equals(comment)) || "f1".equals(formDate.getString("processId"))) {
                            oContentAppSchema = formDate.toJavaObject(OContentAppSchema.class);
                        }
                    }

                    oContentAppSchema.setUpdateDate(new Date());
                    oContentAppSchemaService.updateOContentAppSchema(oContentAppSchema);
                    String processId = formDate.getString("processId");
                    if (Boolean.valueOf(pass) && "f2".equals(processId) && "03".equals(oContentAppSchema.getServiceType())) {
                        try {
                            app(oContentAppSchema);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }

                }
            }
            ProcessInstanceQuery createProcessInstanceQuery = runtimeService.createProcessInstanceQuery();
            ProcessInstanceQuery processInstanceId = createProcessInstanceQuery.processInstanceId(instanceId);
            ProcessInstance singleResult = processInstanceId.singleResult();
            if (null == singleResult) {
                Map<String, Object> map = taskMapper.findByInstanceId(instanceId);
                if (null != map) {
                    String module = String.valueOf(map.get("module"));
                    String business_key = String.valueOf(map.get("business_key"));
//                	String userName= user.getUsername();
//                	taskMapper.updataStatusAndFinshTime(business_key,module,userName,comment);
                    if ("o_anomaly_info".equals(module)) {//异常监控流程处理结束
                        OAnomalyInfo oAnomalyInfo = oAnomalyInfoMapper.selectOAnomalyInfoById(business_key);
//                        oAnomalyInfo.setFinishTime(new Date());
                        oAnomalyInfo.setStatus("02");
                        oAnomalyInfo.setHandleName(username);
                        oAnomalyInfo.setHandleDesc(comment);
                        oAnomalyInfo.setExtrField2("2");
                        oAnomalyInfoMapper.updateOAnomalyInfo(oAnomalyInfo);
                        OMonTar oMonTar = monTarService.selectOMonTarByCode(oAnomalyInfo.getMonTarCode());
                        oMonTar.setMonStatus("01");
                        monTarService.updateOMonTar(oMonTar);
                        remoteIscService.send();
                    }
                    if ("o_content_app_schema".equals(module)) {//资讯流程完成
//                        oAnomalyInfoService

                        OContentAppSchema oContentAppSchema = oContentAppSchemaService.selectOContentAppSchemaById(business_key);
                        oContentAppSchema.setUpdateDate(new Date());
                        oContentAppSchema.setFinishTime(new Date());
                        oContentAppSchemaService.updateOContentAppSchema(oContentAppSchema);

                    }
                    if ("o_content_ad_schema".equals(module)) {//广告流程完成
                        OContentAdSchema oContentAdSchema = oContentAdSchemaService.selectOContentAdSchemaById(business_key);
                        oContentAdSchema.setUpdateDate(new Date());
                        oContentAdSchema.setFinishTime(new Date());
                        oContentAdSchemaService.updateOContentAdSchema(oContentAdSchema);
//                        oAnomalyInfoService
                        if ("03".equals(oContentAdSchema.getServiceType())) {
                            try {
                                ad(oContentAdSchema);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
//            logger.error("error on complete task {}, variables={}", new Object[]{taskId, variables, e});
        }
        return AjaxResult.success();
    }

    @Override
    public List<HistoricActivity> selectHistoryList(HistoricActivity historicActivity) {
        // 说明：以下实现方案是手动封装 开始节点 和 结束节点 的数据，因此不考虑分页功能
//        PageDomain pageDomain = TableSupport.buildPageRequest();
//        Integer pageNum = pageDomain.getPageNum();
//        Integer pageSize = pageDomain.getPageSize();
        List<HistoricActivity> activityList = new ArrayList<>();
        HistoricActivityInstanceQuery query = historyService.createHistoricActivityInstanceQuery();
        if (StringUtils.isNotBlank(historicActivity.getAssignee())) {
            query.taskAssignee(historicActivity.getAssignee());
        }
        if (StringUtils.isNotBlank(historicActivity.getActivityName())) {
            query.activityName(historicActivity.getActivityName());
        }
        List<HistoricActivityInstance> list = query.processInstanceId(historicActivity.getProcessInstanceId())
                .activityType("userTask")
                .finished()
                .orderByHistoricActivityInstanceStartTime()
                .asc()
                .list();
//                .listPage((pageNum - 1) * pageSize, pageNum * pageSize);
        list.forEach(instance -> {
            HistoricActivity activity = new HistoricActivity();
            BeanUtils.copyProperties(instance, activity);
            String taskId = instance.getTaskId();
            List<Comment> comment = taskService.getTaskComments(taskId, "comment");
            if (!CollectionUtils.isEmpty(comment)) {
                activity.setComment(comment.get(0).getFullMessage());
            }
            // 如果是撤销（deleteReason 不为 null），写入审批意见栏
            if (StringUtils.isNotBlank(activity.getDeleteReason())) {
                activity.setComment(activity.getDeleteReason());
            }
            SysUser sysUser = remoteUserService.selectUserByUserName(instance.getAssignee());
            if (sysUser != null) {
                activity.setAssigneeName(sysUser.getNickName());
            }
            activityList.add(activity);
        });

        // 以下手动封装发起人节点的数据
//        HistoricActivity startActivity = new HistoricActivity();
//        query = historyService.createHistoricActivityInstanceQuery();
//        HistoricActivityInstance startActivityInstance = query.processInstanceId(historicActivity.getProcessInstanceId())
//                .activityType("startEvent")
//                .singleResult();
//        BeanUtils.copyProperties(startActivityInstance, startActivity);
//        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
//                .processInstanceId(historicActivity.getProcessInstanceId())
//                .singleResult();
//        startActivity.setAssignee(historicProcessInstance.getStartUserId());
//        SysUser sysUser = remoteUserService.selectUserByUserName(historicProcessInstance.getStartUserId());
//        if (sysUser != null) {
//            startActivity.setAssigneeName(sysUser.getNickName());
//        }
//        startActivity.setComment("提交申请");
//
//        // 手动过滤该条发起人数据
//        boolean necessaryAdd = true;
//        if ((StringUtils.isNotBlank(historicActivity.getActivityName()) && !startActivity.getActivityName().equals(historicActivity.getActivityName()))
//            || (StringUtils.isNotBlank(historicActivity.getAssignee()) && !startActivity.getAssignee().equals(historicActivity.getAssignee()))) {
//            necessaryAdd = false;
//        }
//        if (necessaryAdd) {
//            activityList.add(0, startActivity);
//        }

        // 以下手动封装结束节点的数据
//        HistoricActivity endActivity = new HistoricActivity();
//        query = historyService.createHistoricActivityInstanceQuery();
//        HistoricActivityInstance endActivityInstance = query.processInstanceId(historicActivity.getProcessInstanceId())
//                .activityType("endEvent")
//                .singleResult();
//        if (null != endActivityInstance) {
//            BeanUtils.copyProperties(endActivityInstance, endActivity);
//            endActivity.setAssignee("admin");
//            sysUser = remoteUserService.selectUserByUserName("admin");
//            if (sysUser != null) {
//                endActivity.setAssigneeName(sysUser.getNickName());
//            }
//            endActivity.setComment("自动结束");
//
//            // 手动过滤该条发起人数据
//            necessaryAdd = true;
//            if ((StringUtils.isNotBlank(historicActivity.getActivityName()) && !endActivity.getActivityName().equals(historicActivity.getActivityName()))
//                    || (StringUtils.isNotBlank(historicActivity.getAssignee()) && !endActivity.getAssignee().equals(historicActivity.getAssignee()))) {
//                necessaryAdd = false;
//            }
//            if (necessaryAdd) {
//                activityList.add(endActivity);
//            }
//        }

        return activityList;
    }

    @Override
    public void delegate(String taskId, String fromUser, String delegateToUser) {
        taskService.delegateTask(taskId, delegateToUser);
    }

    @Override
    public void cancelApply(String instanceId, String deleteReason) {
        // 执行此方法后未审批的任务 act_ru_task 会被删除，流程历史 act_hi_taskinst 不会被删除，并且流程历史的状态为finished完成
        runtimeService.deleteProcessInstance(instanceId, deleteReason);
    }

    @Override
    public void suspendOrActiveApply(String instanceId, String suspendState) {
        if ("1".equals(suspendState)) {
            // 当流程实例被挂起时，无法通过下一个节点对应的任务id来继续这个流程实例。
            // 通过挂起某一特定的流程实例，可以终止当前的流程实例，而不影响到该流程定义的其他流程实例。
            // 激活之后可以继续该流程实例，不会对后续任务造成影响。
            // 直观变化：act_ru_task 的 SUSPENSION_STATE_ 为 2
            SysUser user = tokenService.getLoginUser().getSysUser();
            taskMapper.updataLockingUser(user.getUserName(), instanceId);
            runtimeService.suspendProcessInstanceById(instanceId);
        } else if ("2".equals(suspendState)) {
            runtimeService.activateProcessInstanceById(instanceId);
        }
    }


    public void app(OContentAppSchema oContentAppSchema) {
        OInterfaceIndex oInterfaceIndex = interfaceIndexService.selectAddressbycode("0101127");
        String rpcInterface = "test";
        if (null != oInterfaceIndex && null != oInterfaceIndex.getInterfaceAdress()) {
            rpcInterface = oInterfaceIndex.getInterfaceAdress();
        } else {
            System.out.println("0101127接口未配置");
        }

        logger.info("执行资讯审核下架方法2");
        String params = "";
        //构建参数
        /**
         * {
         "serviceCode":"0101127",
         "target":"35101",
         "source":"SGAPP",
         "data":{"platformId":"35101",
         "serialNum":"1111",
         "serviceType":"03",
         "releaseScope":"330000",
         "contentId":"93e6c04bb62d4714a9b8cfd00707a023"}
         *   }
         * }
         */
        Map paramsData = new HashMap();
        paramsData.put("serialNum", oContentAppSchema.getId());
        paramsData.put("serviceType", "06");
        paramsData.put("platformId", "350000");
        paramsData.put("contentId", oContentAppSchema.getNewId());
        paramsData.put("releaseScope", "350000");
                    /*CommonParm commonParm = new CommonParm();
                    commonParm.setTarget("35101");
                    commonParm.setSource("SGAPP");
                    commonParm.setServiceCode("0101127");
                    commonParm.setData(paramsData);
                    params = FastJsonUtil.toJSONString(commonParm);*/
        Map map = new HashMap();
        map.put("serviceCode", "0101127");
        map.put("source", "SGAPP");
        map.put("target", "35101");
        map.put("data", paramsData);
        params = FastJsonUtil.toJSONString(map);
        String rpcResultStr = HttpClientUtil.sendJsonStr(rpcInterface, params).getData();
        //解析返回值
        R r = FastJsonUtil.toBean(rpcResultStr, R.class);

        if (1 == r.getCode()) {
            //编辑表单
            // 当前环节，包括流程的环节，有结束、终止等
            oContentAppSchema.setActName("下架待反馈");
            //流采用标准编码 flowType 01待提交 02待审核 03待发布 04待反馈 05发布失败 06结束 07待提交-审核不通过 08终止 09失败结束
            oContentAppSchema.setFlowType("11");
            oContentAppSchemaService.updateOContentAppSchema(oContentAppSchema);
        } else {
            System.out.println("远程接收参数失败");
        }
    }


    public void ad(OContentAdSchema oContentAdSchema) {
        OInterfaceIndex oInterfaceIndex = interfaceIndexService.selectAddressbycode("0101204");
        if (null == oInterfaceIndex || null == oInterfaceIndex.getInterfaceAdress()) {
            System.out.println("0101204接口未配置");
        }

        logger.info("进入广告下请求接口2");
        String params = "";
        //构建参数
        /**
         * {
         *  "serviceCode": "0101204",
         *  "source": "SGAPP",
         *  "target": "35101",
         *   "data":{
         *    "serialNum":"add96eb0aw5f04ewww32aba67cec3",
         *    "serviceType":"asc2ed",
         *    "platformId":"330000",
         *    "adId":"1cbceb75dc84400ba298450adb053442",
         *    "releaseScope":"330000"
         *   }
         * }
         */
        Map paramsData = new HashMap();
        paramsData.put("serialNum", oContentAdSchema.getId());
        paramsData.put("serviceType", "03");
        paramsData.put("platformId", "350000");
        paramsData.put("adId", oContentAdSchema.getNewId());
        paramsData.put("releaseScope", "350000");

        Map map = new HashMap();
        map.put("serviceCode", "0101204");
        map.put("source", "SGAPP");
        map.put("target", "35101");
        map.put("data", paramsData);
        params = FastJsonUtil.toJSONString(map);
        R<String> rpcResultStr = HttpClientUtil.sendJsonStr(oInterfaceIndex.getInterfaceAdress(), params);
        //解析返回值
        if (rpcResultStr.getCode() != 200) {
            logger.info(oInterfaceIndex.getInterfaceAdress() + "接口调用失败！" + rpcResultStr.getCode());
        }
        R r = FastJsonUtil.toBean(rpcResultStr.getData(), R.class);
    }

}
